#ifndef STEPPER_MOTOR_H_
#define STEPPER_MOTOR_H_

#ifdef __cplusplus
extern "C"
{
#include "main.h"
#include "gpio.h"
#include "74hc595.h" // 依赖移位寄存器控制数据位
#endif
    // 电机信号类型枚举（对应EN/STEP/DIR三种信号）
    typedef enum
    {
        MOTOR_EN,   // 使能信号
        MOTOR_STEP, // 步进信号
        MOTOR_DIR   // 方向信号
    } MotorSignalType;

    // 电机ID枚举（10个轴的唯一标识）
    typedef enum
    {
        MOTOR_A,
        MOTOR_B,
        MOTOR_C,
        MOTOR_D,
        MOTOR_E,
        MOTOR_L,
        MOTOR_M,
        MOTOR_N,
        MOTOR_O,
        MOTOR_P
    } MotorID;

    extern TIM_HandleTypeDef htim4;
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
// 步进电机控制类：基于数据位（而非直接引脚）控制
class StepperMotor
{
public:
    // 构造函数：通过电机ID初始化（不再依赖引脚，而是关联数据位）
    StepperMotor(MotorID motorId, int8_t direction, float stepsPerMm, float maxPosition);

    void init();                                  // 初始化电机（配置数据位相关）
    void enable();                                // 启用电机（通过设置EN信号的数据位）
    void disable();                               // 禁用电机（通过设置EN信号的数据位）
    bool isEnabled() const { return _isEnabled; } // 检查使能状态
    void setDirection(bool forward);              // 设置方向（通过DIR信号的数据位）
    void step();                                  // 发送步进脉冲（通过STEP信号的数据位）
    void setTargetPosition(float position);       // 设置目标位置（毫米）
    void setCurrentPosition(float position);      // 设置当前位置（毫米）
    float getCurrentPosition() const;             // 获取当前位置
    float getTargetPosition() const;              // 获取目标位置
    bool isMoving() const;                        // 检查是否正在运动
    void update();                                // 更新电机状态（处理步进脉冲等）
    void stop();                                  // 停止运动

    // 速度和加速度控制
    void setFeedrate(float feedrate);         // 设置进给速度 (mm/s)
    void setAcceleration(float acceleration); // 设置加速度 (mm/s^2)
    float getCurrentFeedrate() const;         // 获取当前速度
    float getCurrentAcceleration() const;     // 获取当前加速度

    // 新增：获取最大位置
    float getMaxPosition() const { return _maxPosition; }

    void generateStepSignal(void);
    void updatePosition(void);

    bool needStep() const { return _needStep; }

private:
    MotorID _motorId; // 电机ID（关联对应的数据位）

    int8_t _direction; // 方向（1或-1）
    float _stepsPerMm; // 每毫米步数

    float _currentPosition; // 当前位置（毫米）
    float _targetPosition;  // 目标位置（毫米）
    float _maxPosition;     // 最大位置限制 =====新加，轴最大行程

    bool _isMoving;  // 是否正在运动
    bool _stepState; // 步进信号状态（高低电平）
    bool _isEnabled; // 使能状态

    // 运动参数
    float _currentFeedrate;     // 当前速度 (mm/s)
    float _targetFeedrate;      // 目标速度 (mm/s)
    float _currentAcceleration; // 当前加速度 (mm/s^2)
    float _targetAcceleration;  // 目标加速度 (mm/s^2)
    float _startFeedrate;       // 起始速度
    float _maxFeedrate;         // 最大速度

    unsigned long _lastStepTime;   // 上次步进时间（微秒）
    unsigned long _stepInterval;   // 步进间隔（微秒）
    unsigned long _accelStartTime; // 加速开始时间

    // 运动控制方法
    void calculateStepInterval();         // 计算步进间隔
    void updateSpeed();                   // 更新速度
    float calculateSpeed(float distance); // 计算速度

    bool _needStep; // new:标记是否需要执行步进
};
#endif // __cplusplus

#ifdef __cplusplus
extern "C"
{
#endif

    // 电机控制核心函数（操作数据位，通过74hc595输出）
    void motor_set_signal(MotorID motor, MotorSignalType signal, uint8_t state); // 设置电机信号（数据位）
    void motor_update_outputs(void);                                             // 更新输出（将数据位发送到74hc595）

    // 工具函数
    void micros_init(void);
    uint32_t micros(void); // 获取当前时间（微秒）

    int my_abs(int x);
    float my_sqrt(float x);

#ifdef __cplusplus
}
#endif

#endif /* STEPPER_MOTOR_H_ */